package org.bjf.modules.core.web.interceptor;

import com.alibaba.fastjson.JSONObject;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.bjf.modules.core.web.core.ThreadContext;
import org.bjf.utils.IpUtil;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * 日志拦截器
 *
 * @author bjf
 */
@Slf4j
@Component
public class LogInterceptor extends HandlerInterceptorAdapter {

  private static final String REQUEST_ID = "requestId";
  private static final ThreadLocal<Long> TIME_LOCAL = new ThreadLocal<>();

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
    String uuid = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
    MDC.put(REQUEST_ID, uuid);
    // 打印请求参数
    log.info("start uri:{},params:{},ip:{}", request.getRequestURI(),
        JSONObject.toJSON(request.getParameterMap()),
        IpUtil.getClientIp(request));

    TIME_LOCAL.set(System.currentTimeMillis());
    return Boolean.TRUE;
  }

  @Override
  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
      ModelAndView modelAndView) throws Exception {
    // 打印响应时间
    Long start = TIME_LOCAL.get();
    long consumeTime = System.currentTimeMillis() - start;
    String uri = request.getRequestURI();
    log.info("end uri:{},response time:{}", uri, consumeTime);

    if (consumeTime > 1000) {
      log.warn("uri:[{}]响应时间过长:[{} millis]", uri, consumeTime);
    }

    try {
      TIME_LOCAL.remove();
      ThreadContext.clear();
    } catch (Exception ignore) {
    }

    MDC.clear();
  }
}
